/*
 * @(#)CheckBoxtListCellRenderer.java 5/11/2005
 *
 * Copyright 2002 - 2005 JIDE Software Inc. All rights reserved.
 */

package com.element.ui.list;

import com.element.swing.Resource;
import com.element.swing.nullc.NullCheckBox;
import com.element.swing.nullc.NullLabel;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.Locale;


/**
 * Renders an item in a list using JCheckBox.
 */
public class CheckBoxListCellRenderer extends JPanel implements ListCellRenderer, Serializable {
	/**
	 * The checkbox that is used to paint the check box in cell renderer
	 */
	protected AbstractButton _checkBox = new NullCheckBox();
	protected JLabel _label = new NullLabel();

	/**
	 * The label which appears after the check box.
	 */
	protected ListCellRenderer _actualListRenderer;

	public CheckBoxListCellRenderer(ListCellRenderer renderer) {
		_actualListRenderer = renderer;
		_checkBox.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
		_checkBox.setOpaque(false);
		setOpaque(true);
		setLayout(new BorderLayout(0, 0));
		add(_checkBox, BorderLayout.BEFORE_LINE_BEGINS);
	}

	/**
	 * Constructs a default renderer object for an item in a list.
	 */
	public CheckBoxListCellRenderer() {
		this(null);
	}

	/** 显示提示文本，重写是规定提示文本的位置 */
	@Override
	public String getToolTipText(MouseEvent event) {
		if (_actualListRenderer instanceof JComponent) {
			Point p = event.getPoint();
			p.translate(-_checkBox.getWidth(), 0);
			MouseEvent newEvent = new MouseEvent(((JComponent) _actualListRenderer), event.getID(),
					event.getWhen(),
					event.getModifiersEx(),
					p.x, p.y, event.getClickCount(),
					event.isPopupTrigger());

			String tip = ((JComponent) _actualListRenderer).getToolTipText(newEvent);

			if (tip != null) return tip;
		}
		return super.getToolTipText(event);
	}

	public Component getListCellRendererComponent(JList list,
	                                              Object value,
	                                              int index,
	                                              boolean isSelected,
	                                              boolean cellHasFocus) {
		applyComponentOrientation(list.getComponentOrientation());
		setLocale(list.getLocale());

		Object actualValue;
		if (list instanceof CheckBoxList) {
			CheckBoxListSelectionModel selectionModel = ((CheckBoxList) list).getCheckBoxListSelectionModel();
			if (selectionModel != null) {
				boolean enabled = list.isEnabled()
						&& ((CheckBoxList) list).isCheckBoxEnabled()
						&& ((CheckBoxList) list).isCheckBoxEnabled(index);
				if (!enabled && !isSelected) {
					if (getBackground() != null) {
						setForeground(getBackground().darker());
					}
				}
				_checkBox.setEnabled(enabled);
				_checkBox.setSelected(selectionModel.isSelectedIndex(index));
			}
			actualValue = value;
		} else {
			throw new IllegalArgumentException("CheckBoxListCellRenderer should only be used for CheckBoxList.");
		}

		if (_actualListRenderer != null) {
			JComponent listCellRendererComponent = (JComponent) _actualListRenderer.getListCellRendererComponent(list, actualValue, index, isSelected, cellHasFocus);

			// make sure the (All) is converted to the localized string.
			if (listCellRendererComponent instanceof JLabel) {
				String v = convertElementToString(getLocale(), ((JLabel) listCellRendererComponent).getText());
				((JLabel) listCellRendererComponent).setText(v);
			}

			if (list instanceof CheckBoxList) {
				if (!((CheckBoxList) list).isCheckBoxVisible(index)) {
					return listCellRendererComponent;
				}
			}
			Border border = listCellRendererComponent.getBorder();
			setBorder(border);
			listCellRendererComponent.setBorder(BorderFactory.createEmptyBorder());
			if (getComponentCount() == 2) {
				remove(1);
			}
			add(listCellRendererComponent);

			// copy the background and foreground for the renderer component
			setBackground(listCellRendererComponent.getBackground());
			listCellRendererComponent.setBackground(null);
			setForeground(listCellRendererComponent.getForeground());
			listCellRendererComponent.setForeground(null);
			listCellRendererComponent.setEnabled(_checkBox.isEnabled());
		} else {
			if (isSelected) {
				setBackground(list.getSelectionBackground());
				setForeground(list.getSelectionForeground());
			} else {
				setBackground(list.getBackground());
				setForeground(list.getForeground());
			}
			if (getComponentCount() == 2) {
				remove(1);
			}
			add(_label);
			customizeDefaultCellRenderer(actualValue);
			setFont(list.getFont());
		}

		return this;
	}

	private String convertElementToString(Locale locale, Object value) {
		if (CheckBoxList.ALL_ENTRY.equals(value) || "(All)".equals(value)) {
			return Resource.getResourceBundle(locale).getString("CheckBoxList.all");
		}
		return (value == null) ? "" : value.toString();
	}

	/**
	 * Customizes the cell renderer. By default, it will use toString to covert the object and use it as the text for
	 * the checkbox. You can subclass it to set an icon, change alignment etc. Since "this" is a JCheckBox, you can call
	 * all methods available on JCheckBox in the overridden method.
	 *
	 * @param value the value on the cell renderer.
	 */
	protected void customizeDefaultCellRenderer(Object value) {
		if (value instanceof Icon) {
			_label.setIcon((Icon) value);
			_label.setText("");
		} else {
			_label.setIcon(null);
			_label.setText(convertElementToString(getLocale(), value));
		}
	}


	/**
	 * A subclass of CheckBoxListCellRenderer that implements UIResource. CheckBoxListCellRenderer doesn't implement
	 * UIResource directly so that applications can safely override the cellRenderer property with
	 * CheckBoxListCellRenderer subclasses.
	 * <p/>
	 * <strong>Warning:</strong> Serialized objects of this class will not be compatible with future Swing releases. The
	 * current serialization support is appropriate for short term storage or RMI between applications running the same
	 * version of Swing.  As of 1.4, support for long term storage of all JavaBeans<sup><font size="-2">TM</font></sup>
	 * has been added to the <code>java.beans</code> package. Please see {@link java.beans.XMLEncoder}.
	 */
	public static class UIResource extends CheckBoxListCellRenderer implements javax.swing.plaf.UIResource {
	}


	public ListCellRenderer getActualListRenderer() {
		return _actualListRenderer;
	}

	public void setActualListRenderer(ListCellRenderer actualListRenderer) {
		_actualListRenderer = actualListRenderer;
	}
}
